package com.bristua.mall.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author zlf
 * @ClassName: DateUtil
 * @Description: 日期工具类
 * @date 2017年2月10日 下午2:51:38
 */

public class DateUtil {
    public static final long daySpan = 24 * 60 * 60 * 1000;
    public static final String DAY="DAY";
    public static final String MONTH="MONTH";
    public static final String MINUTE="MINUTE";
    public static final String HOURS="HOURS";
    public static final String FORMAT1="yyyy-MM-dd HH:mm:ss";
    public static SimpleDateFormat sdf_date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);

//    public static void test() {
//        try {
//            int i = 1 / 0;
//        } catch (Exception e) {
//            throw new SystemException(CommonCode.TIMECHANGEEXCEPTION.getCode(), CommonCode.TIMECHANGEEXCEPTION.getMsg(),e);
////            throw new RuntimeException("参数错",e);
//            // e.printStackTrace();
//            //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//        }
//    }


    public static boolean isDate(String strDate) {
        Pattern pattern = Pattern
                .compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
        Matcher m = pattern.matcher(strDate);
        if (m.matches()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取当前日期(yyyyMMdd)
     *
     * @return
     */
    public static String getDate() {
        Date date = new Date();
        String strDate = sdf_date.format(date);
        return strDate;
    }

    /**
     * 获取当前时间(yyyyMMddHHmmss)
     *
     * @return
     */
    public static String getDateTime() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String strDate = sdf.format(date);
        return strDate;
    }


    public static String getDateTime2() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String strDate = sdf.format(date);
        return strDate;
    }

    public static String getDateTime3() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strDate = sdf.format(date);
        return strDate;
    }

    /**
     * 获取当前时间（时分秒）HHmmss
     *
     * @return
     */
    public static String getTime() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
        String strDate = sdf.format(date);
        return strDate;
    }

    /**
     * 获取当前时间(年月日时分秒毫秒)
     *
     * @return
     */
    public static String getAllTime() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSSS");
        String strDate = sdf.format(date);
        return strDate;
    }

    /**
     * 获取当前年份
     *
     * @return
     */
    public static String getCurrentYear() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        String strDate = sdf.format(date);
        return strDate + "0101";
    }

    /**
     * 返回格式化日期
     *
     * @param strDate
     * @param patternOld
     * @param patternNew
     * @return
     * @throws Exception
     */
    public static String getFormatDate(String strDate, String patternOld, String patternNew) throws Exception {
        if (strDate == null || strDate.equals("")) {
            return strDate;
        }
        try {
            SimpleDateFormat sdf1 = new SimpleDateFormat(patternOld);
            Date date = sdf1.parse(strDate);
            SimpleDateFormat sdf2 = new SimpleDateFormat(patternNew);
            return sdf2.format(date);
        } catch (Exception e) {
          e.printStackTrace();
        }
        return null;
    }

    public static String getFormatToday(String Format) {
        return new SimpleDateFormat(Format).format(new Date());
    }

    /* 这部分专门用于获取Timestamp格式时间 */
    public static Timestamp getTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    public static Timestamp getTimestamp(String date, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date date1 = sdf.parse(date);
            return new Timestamp(date1.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static Date getDate(String date, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.parse(date);
        } catch (Exception e) {
            return new Date();
        }
    }

    /**
     * @Title: timestampToString @Description: timestamp转String @param @param
     * date : 日期 @param @param format : 格式 @param @return 参数说明 @return String
     * 返回类型 @throws
     */
    public static String timestampToString(Timestamp date, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            long time = date.getTime();
            Date newDate = new Date(time);
            return sdf.format(newDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param date:日期
     * @param format:格式
     * @return
     */
    public static String dateToString(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * @Title: stringTimeCompareCurrentTime @Description: 和当前时间比较 @param @param
     * dateStr @param @param format @param @return 参数说明 @return Timestamp
     * 返回类型 @throws
     */
    public static boolean stringTimeCompareCurrentTime(String dateStr) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date parse = sdf.parse(dateStr);
            String timestampToString = timestampToString(new Timestamp(System.currentTimeMillis()), "yyyy-MM-dd");
            Date current = sdf.parse(timestampToString);
            if (current.getTime() > parse.getTime()) {
                return true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return false;

    }

    public static Timestamp stringToTimestamp(String dateStr) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Calendar cal = Calendar.getInstance();
        try {
            Date date = sdf.parse(dateStr);
            date.getTime();
            cal.setTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return new Timestamp(cal.getTimeInMillis());

    }


    public static int getMonth(String dateStr){
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = sdf.parse(dateStr);
            cal.setTime(date);
            return cal.get(Calendar.MONTH)+1;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 获取某年某月的天数
     *
     * @param year
     * @param month
     * @return
     */
    public static int getMonthDays(int year, int month) {
        int no = 0;
        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
            no = 31;
        } else if (month == 4 || month == 6 || month == 9 || month == 11) {
            no = 30;
        } else if (month == 2) {
            if (year % 4 == 0) {
                no = 29;
            } else {
                no = 28;
            }
        }

        return no;
    }

    /**
     * 获取明天日期(yyyyMMdd)
     *
     * @return
     */
    public static String getTomorrow() {
        Date date = new Date(new Date().getTime() + daySpan);
        String strDate = sdf_date.format(date);
        return strDate;
    }

    public static String getAfterTomorrow() {
        Date date = new Date(new Date().getTime() + 2 * daySpan);
        String strDate = sdf_date.format(date);
        return strDate;
    }

    /**
     * 获取昨天日期(yyyyMMdd)
     *
     * @return
     */
    public static String getYesterday() {
        Date date = new Date(new Date().getTime() - daySpan);
        String strDate = sdf_date.format(date);
        return strDate;
    }

    /**
     * 获取n天之后的日期，n可为负
     *
     * @param format
     * @param n
     * @return
     */
    public static String getNDaysAfter(String oldDate, String format, int n) {
        String strDate = "";
        try {
            SimpleDateFormat sf = new SimpleDateFormat(format);
            Date date = new Date(sf.parse(oldDate).getTime() + n * daySpan);
            strDate = sf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strDate;
    }


    /**
     * 获取n天之后的日期，n可为负
     *
     * @param n
     * @return
     */
    public static String getNDaysAfter(Date oldDate, int n) {
        String strDate = "";
        try {
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            String s = dateToString(oldDate, "yyyy-MM-dd");
            Date date = new Date(sf.parse(s).getTime() + n * daySpan);
            strDate = sf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strDate;
    }


    /**
     * 获得n个月前的日期(未处理n>12的情况)
     *
     * @param Format
     * @param n
     * @return
     */

    /**
     * 时间范围(毫秒) 报错返回null
     *
     * @param dateStr1
     * @param dateStr2
     * @param format
     * @return Long dateStr1-dateStr2
     */
    public static Long msecRange(String dateStr1, String dateStr2, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date date1 = sdf.parse(dateStr1);
            Date date2 = sdf.parse(dateStr2);
            return date1.getTime() - date2.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 时间范围（月） 报错返回null
     *
     * @param dateStr1
     * @param dateStr2
     * @param format
     * @return Long dateStr1-dateStr2
     */
    public static Integer monthRange(String dateStr1, String dateStr2, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Date date1 = sdf.parse(dateStr1);
            Date date2 = sdf.parse(dateStr2);
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMM");
            String formatDate1 = sdf2.format(date1);
            String formatDate2 = sdf2.format(date2);
            int year1 = Integer.parseInt(formatDate1.substring(0, 4));
            int year2 = Integer.parseInt(formatDate2.substring(0, 4));
            int month1 = Integer.parseInt(formatDate1.substring(4, 6));
            int month2 = Integer.parseInt(formatDate2.substring(4, 6));
            int monthRange = month1 - month2;
            int yearRange = year1 - year2;
            return yearRange * 12 + monthRange;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static double daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        double between_days = (time2 - time1) / (1000 * 3600 * 24 * 1.0);
        return between_days;
    }


    /**
     * 字符串的日期格式的计算
     */
    public static int daysBetween(String smdate, String bdate) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar cal = Calendar.getInstance();
            cal.setTime(sdf.parse(smdate));
            long time1 = cal.getTimeInMillis();
            cal.setTime(sdf.parse(bdate));
            long time2 = cal.getTimeInMillis();
            long between_days = (time2 - time1) / (1000 * 3600 * 24);
            return Integer.parseInt(String.valueOf(between_days));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return 0;

    }

    /**
     * 字符串的日期格式的计算
     */
    public static int timeDifference(String startTime, String endTime,String formate,String type) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(formate);
            Calendar cal = Calendar.getInstance();
            cal.setTime(sdf.parse(startTime));
            long time1 = cal.getTimeInMillis();
            cal.setTime(sdf.parse(endTime));
            long time2 = cal.getTimeInMillis();
            long between_days = 0 ;
            if(DAY.equals(type)){
                 between_days = (time2 - time1) / (1000 * 3600 * 24);
                return Integer.parseInt(String.valueOf(between_days));
            }
            if(HOURS.equals(type)){
                 between_days = (time2 - time1) / (1000 * 3600);
                return Integer.parseInt(String.valueOf(between_days));
            }
            if(MINUTE.equals(type)){
                 between_days = (time2 - time1) / (1000*60);
                return Integer.parseInt(String.valueOf(between_days));
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return 0;

    }


    public static int getAge(String dateOfBirth) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sdf.parse(dateOfBirth);
            int age = 0;
            Calendar born = Calendar.getInstance();
            Calendar now = Calendar.getInstance();
            if (dateOfBirth != null) {
                now.setTime(new Date());
                born.setTime(date);
                if (born.after(now)) {
                    throw new IllegalArgumentException("年龄不能超过当前日期");
                }
                age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);
                int nowDayOfYear = now.get(Calendar.DAY_OF_YEAR);
                int bornDayOfYear = born.get(Calendar.DAY_OF_YEAR);
                System.out.println("nowDayOfYear:" + nowDayOfYear + " bornDayOfYear:" + bornDayOfYear);
                if (nowDayOfYear < bornDayOfYear) {
                    age -= 1;
                }
            }
            return age;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;

    }


    /**
     * 日期转星期
     *
     * @param time
     * @return
     */
    public static String getWeekDayByTime(String time) {
        try {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            calendar.setTime(sdf.parse(time));
            int i = calendar.get(Calendar.DAY_OF_WEEK);
            SimpleDateFormat sdf2 = new SimpleDateFormat("E");
            System.out.println(sdf2.format(calendar.getTime()));
            return sdf2.format(calendar.getTime());
        } catch (Exception ex) {
            ex.printStackTrace();
//            return null;
        }
        return null;
    }

    public static String getCurrentYearStr() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        return year + "";
    }


    public static String getAgeMonth(String time){
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar birthday = Calendar.getInstance();
            birthday.setTime(sdf.parse(time));
//        Calendar birthday = new GregorianCalendarregorianCalendar(1985, 10, 10);//2010年10月12日，month从0开始
            Calendar now = Calendar.getInstance();
            int day = now.get(Calendar.DAY_OF_MONTH) - birthday.get(Calendar.DAY_OF_MONTH);
            int month = now.get(Calendar.MONTH) - birthday.get(Calendar.MONTH);
            int year = now.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
            //按照减法原理，先day相减，不够向month借；然后month相减，不够向year借；最后year相减。
            if(day<0){
                month -= 1;
                now.add(Calendar.MONTH, -1);//得到上一个月，用来得到上个月的天数。
                day = day + now.getActualMaximum(Calendar.DAY_OF_MONTH);
            }
            if(month<0){
                month = (month+12)%12;
                year--;
            }
            System.out.println("年龄："+year+"年"+month+"月"+day+"天");
            return year+"岁"+(month==0?"":month+"月");

        }catch (Exception ex){
            ex.printStackTrace();
        }
        return "";

    }







    public static void main(String[] args) throws Exception {

        int i = DateUtil.timeDifference("2019-04-28 12:11:12", "2019-04-28 12:19:12", DateUtil.FORMAT1, DateUtil.MINUTE);
        String time ="1992-06-01";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar birthday = Calendar.getInstance();
        birthday.setTime(sdf.parse(time));
//        Calendar birthday = new GregorianCalendarregorianCalendar(1985, 10, 10);//2010年10月12日，month从0开始
        Calendar now = Calendar.getInstance();
        int day = now.get(Calendar.DAY_OF_MONTH) - birthday.get(Calendar.DAY_OF_MONTH);
        int month = now.get(Calendar.MONTH) - birthday.get(Calendar.MONTH);
        int year = now.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
        //按照减法原理，先day相减，不够向month借；然后month相减，不够向year借；最后year相减。
        if(day<0){
            month -= 1;
            now.add(Calendar.MONTH, -1);//得到上一个月，用来得到上个月的天数。
            day = day + now.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        if(month<0){
            month = (month+12)%12;
            year--;
        }
        System.out.println("年龄："+year+"年"+month+"月"+day+"天");




//        int month = getMonth("1959-03-01");
////        int i = daysBetween("2017-10-25 ", "2017-10-26");
//        System.out.println(month);
//        String str = "2017-10-31";
//        Calendar calendar = Calendar.getInstance();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        calendar.setTime(sdf.parse(str));
//        int i = calendar.get(Calendar.DAY_OF_WEEK);
//		if(i == 1){
//			System.out.println("今天是星期日");
//		}else{
//			System.out.println("今天是星期"+(i-1));
//		}

//		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss E");
//		System.out.println(sdf1.format(calendar.getTime()));
//        String nDaysAfter = DateUtil.getNDaysAfter("2017-10-01", "yyyy-MM-dd", -10);
//        System.out.print(nDaysAfter);
//        SimpleDateFormat sdf2 = new SimpleDateFormat("E");
//        System.out.println(sdf2.format(calendar.getTime()));
    }
}
